package com.tutucms.common.javamail;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.util.List;
import java.util.Properties;

/**
 * Title:邮件发送类
 * Description:cn.com.wxd.util.service.javamail
 * <p>
 * Company: Amumu管理平台
 * Copyright: Copyright (c) 2015
 * All right reserved.
 * Created time: 2016-4-8 下午3:27:20
 *
 * @author WangXuDong
 * @version 1.0
 */
public class MailSender {
    private static final Logger log = LoggerFactory.getLogger(MailSender.class);
    /**
     * 系统参数
     */
    private final transient Properties props = System.getProperties();
    /**
     * 邮箱服务器登录验证
     * transient 不需要序列化
     */
    private transient MailAuthenticator authenticator;
    /**
     * 邮箱的session
     */
    private transient Session session;

    private String fromName;

    /**
     * 自定义用户创建实例
     *
     * @param smtpHostName smtp值
     * @param username     默认发件邮箱
     * @param password     密码
     * @param port         端口
     */
    public MailSender(String smtpHostName, String username, String password, String port) {
        if (smtpHostName == null || smtpHostName.equals("")) {
            smtpHostName = "smtp." + username.split("@")[1];
        }
        if (port == null || port.equals("")) {
            port = "465";
        }
        init(username, password, smtpHostName, port);
    }

    /**
     * 默认从配置文件中创建实例
     */
    public MailSender() {
        String username = MailInfo.getEmail();
        String password = MailInfo.getPassword();
        String smtpHost = MailInfo.getSmtp();
        fromName = MailInfo.getFromName();
        String port = MailInfo.getPort();
        if (smtpHost == null || smtpHost.equals("")) {
            smtpHost = "smtp." + username.split("@")[1];
        }
        if (port == null || port.equals("")) {
            port = "465";
        }
        init(username, password, smtpHost, port);
    }

    /**
     * 初始化
     *
     * @param username     发送邮件的用户名(地址)
     * @param password     密码
     * @param smtpHostName SMTP主机地址
     */
    private void init(String username, String password, String smtpHostName, String port) {
        // 初始化props
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.host", smtpHostName);
        if (MailInfo.isEncryp()) {
            props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            props.setProperty("mail.smtp.socketFactory.port", port);
        }
        props.setProperty("mail.smtp.port", port);
        props.setProperty("mail.debug", String.valueOf(MailInfo.isDebug()));
        // 验证
        authenticator = new MailAuthenticator(username, password);
        // 创建session
        session = Session.getInstance(props, authenticator);
    }

    /**
     * 发送邮件
     *
     * @param recipient 收件人邮箱地址
     * @param subject   邮件主题
     * @param content   邮件内容
     * @return 发送是否成功
     */
    public boolean send(String recipient, String subject, String content) {
        // 创建mime类型邮件
        if (recipient == null || recipient.equals("")) {
            log.error("邮件发送发件人不能为空!");
            return false;
        }
        if (subject == null || subject.equals("")) {
            log.error("邮件主题不能为空!");
            return false;
        }
        if (content == null || content.equals("")) {
            log.error("邮件内容不能为空!");
            return false;
        }
        try {
            final MimeMessage message = new MimeMessage(session);
            // 设置发信人
            message.setFrom(new InternetAddress(authenticator.getUsername(), fromName, "UTF-8"));
            // 设置收件人
            message.setRecipient(Message.RecipientType.TO, new InternetAddress(recipient));
            // 设置主题
            message.setSubject(subject);
            // 设置邮件内容
            message.setContent(content, "text/html;charset=utf-8");
            // 发送
            Transport.send(message);
            return true;
        } catch (Exception e) {
            log.error("邮件发送错误!" + e.getMessage());
            return false;
        }

    }

    /**
     * 群发邮件
     *
     * @param recipients 收件人列表
     * @param subject    主题
     * @param content    内容
     * @return 是否成功
     */
    public boolean send(List<String> recipients, String subject, String content) {
        // 创建mime类型邮件
        final MimeMessage message = new MimeMessage(session);
        try {
            // 设置发信人
            message.setFrom(new InternetAddress(authenticator.getUsername(), fromName, "UTF-8"));
            // 设置收件人们
            final int num = recipients.size();
            InternetAddress[] addresses = new InternetAddress[num];
            for (int i = 0; i < num; i++) {
                addresses[i] = new InternetAddress(recipients.get(i));
            }
            message.setRecipients(Message.RecipientType.TO, addresses);
            // 设置主题
            message.setSubject(subject);
            // 设置邮件内容
            message.setContent(content, "text/html;charset=utf-8");
            // 发送
            Transport.send(message);
            return true;
        } catch (Exception e) {
            log.error("邮件发送错误!" + e.getMessage());
            return false;
        }
    }

    /**
     * 发送带图片的邮件
     *
     * @param recipients 收件人列表
     * @param subject    主题
     * @param content    内容
     * @param img        图片数据源
     * @return 是否成功
     */
    public boolean send(List<String> recipients, String subject, String content, FileDataSource img) {
        // 创建mime类型邮件
        final MimeMessage message = new MimeMessage(session);
        try {
            // 设置发信人
            message.setFrom(new InternetAddress(authenticator.getUsername(), fromName, "UTF-8"));
            // 设置收件人们
            final int num = recipients.size();
            InternetAddress[] addresses = new InternetAddress[num];
            for (int i = 0; i < num; i++) {
                addresses[i] = new InternetAddress(recipients.get(i));
            }
            message.setRecipients(Message.RecipientType.TO, addresses);
            // 设置主题
            message.setSubject(subject);
            // 设置邮件内容
            message.setContent(content + "<img src='cid:xxx.jpg'/>", "text/html;charset=utf-8");
            // 准备邮件正文数据
            MimeBodyPart text = new MimeBodyPart();
            // 准备图片数据
            MimeBodyPart image = new MimeBodyPart();
            DataHandler dh = new DataHandler(img);
            image.setDataHandler(dh);
            image.setContentID("xxx.jpg");
            // 描述数据关系
            MimeMultipart mm = new MimeMultipart();
            mm.addBodyPart(text);
            mm.addBodyPart(image);
            mm.setSubType("related");
            // 发送
            Transport.send(message);
            return true;
        } catch (Exception e) {
            log.error("邮件发送错误!" + e.getMessage());
            return false;
        }

    }

    /**
     * 发送带附件的邮件
     *
     * @param recipients 收件人列表
     * @param subject    主题
     * @param content    内容
     * @param file       图片数据源
     * @return 是否成功
     */
    public boolean send(List<String> recipients, String subject, FileDataSource file, String content) {
        // 创建mime类型邮件
        final MimeMessage message = new MimeMessage(session);
        try {
            // 设置发信人
            message.setFrom(new InternetAddress(authenticator.getUsername(), fromName, "UTF-8"));
            // 设置收件人们
            final int num = recipients.size();
            InternetAddress[] addresses = new InternetAddress[num];
            for (int i = 0; i < num; i++) {
                addresses[i] = new InternetAddress(recipients.get(i));
            }
            message.setRecipients(Message.RecipientType.TO, addresses);
            // 设置主题
            message.setSubject(subject);
            // 设置邮件内容
            message.setContent(content, "text/html;charset=utf-8");
            // 准备邮件正文数据
            MimeBodyPart text = new MimeBodyPart();
            //创建邮件附件
            MimeBodyPart attach = new MimeBodyPart();
            DataHandler dh = new DataHandler(file);
            attach.setDataHandler(dh);
            attach.setFileName(dh.getName());  //
            //创建容器描述数据关系
            MimeMultipart mp = new MimeMultipart();
            mp.addBodyPart(text);
            mp.addBodyPart(attach);
            mp.setSubType("mixed");
            // 发送
            Transport.send(message);
            return true;
        } catch (Exception e) {
            log.error("邮件发送错误!" + e.getMessage());
            return false;
        }

    }
}
